using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Text.RegularExpressions;

namespace AdminApiTemplate.Common.Helpers
{
    public class ValidationHelper
    {
        public static List<ValidationResult> Validate<T>(T model) where T : class, new()
        {
            var ttype = typeof(T);
            return Validate(ttype, model);
        }

        private static List<ValidationResult> Validate(object model)
        {
            var ttype = model.GetType();
            return Validate(ttype, model);
        }

        private static List<ValidationResult> Validate(Type ttype, object model)
        {
            var invalids = new List<ValidationResult>();
            var tps = ttype.GetProperties();
            foreach (var tp in tps)
            {
                var valid = true;
                var validation = new ValidationResult
                {
                    Display = tp.Name,
                    Name = tp.Name
                };

                var descriptionAttr = tp.GetCustomAttribute<DescriptionAttribute>();
                if (descriptionAttr != null)
                {
                    validation.Display = descriptionAttr.Description;
                }

                var displayAttr = tp.GetCustomAttribute<DisplayAttribute>();
                if (displayAttr != null)
                {
                    validation.Display = displayAttr.Name;
                }

                var obj = tp.GetValue(model, null);
                if (obj != null && !string.IsNullOrEmpty(obj.ToString()))
                {
                    var val = obj.ToString();
                    var regexAttr = tp.GetCustomAttribute<RegularExpressionAttribute>();
                    if (regexAttr != null)
                    {
                        if (!Regex.IsMatch(val, regexAttr.Pattern))
                        {
                            valid = false;
                            validation.Message = regexAttr.ErrorMessage;
                        }
                    }

                    var maxLengthAttr = tp.GetCustomAttribute<MaxLengthAttribute>();
                    if (maxLengthAttr != null)
                    {
                        if (val.Length > maxLengthAttr.Length)
                        {
                            valid = false;
                            validation.Message = string.Format(maxLengthAttr.ErrorMessage, maxLengthAttr.Length);
                        }
                    }
                }
                else
                {
                    var requiredAttr = tp.GetCustomAttribute<RequiredAttribute>();
                    if (requiredAttr != null)
                    {
                        valid = false;
                        validation.Message = requiredAttr.ErrorMessage;
                    }
                }

                if (!valid)
                {
                    invalids.Add(validation);
                }
            }

            return invalids;
        }

        public static string Validate2<T>(T model) where T : class, new()
        {
            var invalids = Validate(model);
            var errors = string.Join(",", invalids.Select(o => $"{o.Display}{o.Message}"));
            return errors;
        }

        private static string Validate2(object model)
        {
            var invalids = Validate(model);
            var errors = string.Join(",", invalids.Select(o => $"{o.Display}{o.Message}"));
            return errors;
        }
    }

    public class ValidationResult
    {
        /// <summary>
        /// 字段显示
        /// </summary>
        public string Display { get; set; }

        /// <summary>
        /// 字段
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }
    }
}
